package com.base.server.common.realm;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.base.server.common.config.RedisClient;
import com.base.server.common.config.jwt.JwtToken;
import com.base.server.common.config.jwt.JwtUtil;
import com.base.server.common.constant.Constant;
import com.base.server.modules.user.entity.UserInfo;
import com.base.server.modules.user.mapper.UserInfoMapper;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author HuTongFu
 * @description: 用户Realm
 * @since 2019/6/6 15:47
 */
@Component
public class UserRealm extends AuthorizingRealm {
    private static Logger logger = LoggerFactory.getLogger(UserRealm.class);

    @Resource
    UserInfoMapper userInfoMapper;

    @Autowired
    private RedisClient redis;

    /**
     * 大坑，必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {

        return token instanceof JwtToken;
    }

    /**
     * 授予角色权限
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        Set<String> realmNames = principalCollection.getRealmNames();
//        Set<String> roles = new HashSet<>();
//        Set<String> permissions = new HashSet<>();
//        UserDto user = (UserDto) principalCollection.getPrimaryPrincipal();
//        //设置角色
//        roles.add("admin");
//        roles.add("admin1");
//        //设置权限
//        permissions.add("admin:perm1");
//        permissions.add("user:del:del");
//        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        //添加角色
//        info.setRoles(roles);
//        //添加权限
//        logger.debug("授权方法执行");
//        info.setStringPermissions(permissions);
        return null;
    }

    /**
     * 登录验证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//        String password = String.valueOf(token.getPassword());
//        QueryWrapper<UserInfoVo> query = Wrappers.query(new UserInfoVo());
//        query.eq("ui.login_name", token.getUsername());
//        UserInfoVo userInfo = userInfoMapper.selectOne(query);
//        if (userInfo == null) {
//            throw new UnknownAccountException("用户不存在");
//        }
//        if (!password.equals(userInfo.getPassword())) {
//            throw new IncorrectCredentialsException("密码不正确");
//        }
//
//        return new SimpleAuthenticationInfo(userInfo, password, this.getName());

        String token = (String) authenticationToken.getCredentials();
        String account = JwtUtil.getClaim(token, Constant.JWT.ACCOUNT);

        if (account == null) {
            throw new AuthenticationException("token 失效");
        }
        // 开始认证，要AccessToken认证通过，且Redis中存在RefreshToken，且两个Token时间戳一致
        if (JwtUtil.verify(token) && redis.hasKey(Constant.RedisConstant.PREFIX_TOKEN_REFRESH_TIME + account)) {
            // 获取RefreshToken的时间戳
            String currentTimeMillisRedis = redis.get(Constant.RedisConstant.PREFIX_TOKEN_REFRESH_TIME + account).toString();
            // 获取AccessToken时间戳，与RefreshToken的时间戳对比
            if (JwtUtil.getClaim(token, Constant.JWT.CURRENT_TIME_MILLIS).equals(currentTimeMillisRedis)) {
                return new SimpleAuthenticationInfo(token, token, this.getName());
            }
        } else {
            QueryWrapper<UserInfo> query = Wrappers.query(new UserInfo());
            query.eq("login_name", account);
            UserInfo userInfo = userInfoMapper.selectOne(query);
            if (userInfo == null) {
                throw new UnknownAccountException("用户不存在");
            }
//            if (!password.equals(userInfo.getPassword())) {
//                throw new IncorrectCredentialsException("密码不正确");
//            }

        }

        throw new AuthenticationException("Token已过期");
    }
}
